<?php
namespace Sdk\Order\WidgetRule;

use Marmot\Core;
use Respect\Validation\Validator as V;

use Sdk\Order\Model\OrderLTL;

class OrderLTLWidgetRule
{
    const ITEMS_KEYS = array(
        "description",
        "itemNumber",
        "length",
        "width",
        "height",
        "weight",
        "weightUnit",
        "goodsLevel",
        "stackable",
        "turnable",
        "packingType"
    );
    //验证货物信息格式为数组，且对应字段都存在
    public function items($items) : bool
    {
        $amazonLTLWidgetRule = new AmazonLTLWidgetRule();
        $amazonFTLWidgetRule = new AmazonFTLWidgetRule();

        if (empty($items) || !V::arrayType()->validate($items)) {
            Core::setLastError(ITEMS_FORMAT_INCORRECT);
            return false;
        }

        foreach ($items as $item) {
            foreach ($item as $key => $value) {
                if (!in_array($key, self::ITEMS_KEYS)) {
                    Core::setLastError(ITEMS_FORMAT_INCORRECT);
                    return false;
                }
                if ($key == 'description' && !$this->description($value)) {
                    return false;
                }
                if ($key == 'itemNumber' && !$amazonLTLWidgetRule->itemNumber($value)) {
                    return false;
                }
                if ($key == 'length' && !$amazonFTLWidgetRule->length($value)) {
                    return false;
                }
                if ($key == 'width' && !$amazonFTLWidgetRule->width($value)) {
                    return false;
                }
                if ($key == 'height' && !$amazonFTLWidgetRule->height($value)) {
                    return false;
                }
                if ($key == 'weight' && !$amazonLTLWidgetRule->weight($value)) {
                    return false;
                }
                if ($key == 'weightUnit' && !$amazonLTLWidgetRule->weightUnit($value)) {
                    return false;
                }
                if ($key == 'goodsLevel' && !$this->goodsLevel($value)) {
                    return false;
                }
                if ($key == 'stackable' && !$this->stackable($value)) {
                    return false;
                }
                if ($key == 'turnable' && !$this->turnable($value)) {
                    return false;
                }
                if ($key == 'packingType' && !$amazonFTLWidgetRule->packingType($value)) {
                    return false;
                }
            }
        }
        return true;
    }

    //验证货物等级：字符串
    public function goodsLevel($goodsLevel) : bool
    {
        if (!V::stringType()->validate($goodsLevel)) {
            Core::setLastError(GOODSLEVEL_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    //验证是否可叠放范围：[0,1]
    public function stackable($stackable) : bool
    {
        if (!in_array($stackable, OrderLTL::STACKABLE)) {
            Core::setLastError(STACKABLE_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    //验证是否可转动范围：[0,1]
    public function turnable($turnable) : bool
    {
        if (!in_array($turnable, OrderLTL::TURNABLE)) {
            Core::setLastError(TURNABLE_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    // 946656000 代表 2000-01-01 00:00:00
    // 4102415999 代表 2099-12-31 23:59:59
    const MIN_TIMESTAMP = 946656000;
    const MAX_TIMESTAMP = 4102415999;
    public function bookingPickupDate($bookingPickupDate) : bool
    {
        if (!V::intVal()->between(
            self::MIN_TIMESTAMP,
            self::MAX_TIMESTAMP
        )->validate($bookingPickupDate)) {
            Core::setLastError(BOOKINGPICKUPDATE_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    const ZIPCODE_MIN_LENGTH = 1;
    const ZIPCODE_MAX_LENGTH = 50;
    //验证取货邮编长度：1-50个字符
    public function pickupZipCode($pickupZipCode) : bool
    {
        if (!V::stringType()->length(
            self::ZIPCODE_MIN_LENGTH,
            self::ZIPCODE_MAX_LENGTH
        )->validate($pickupZipCode)) {
            Core::setLastError(PICKUPZIPCODE_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    public function pickupAddressType($pickupAddressType) : bool
    {
        if (!V::stringType()->validate($pickupAddressType)) {
            Core::setLastError(PICKUPADDRESSTYPE_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    public function deliveryZipCode($deliveryZipCode) : bool
    {
        if (!V::stringType()->length(
            self::ZIPCODE_MIN_LENGTH,
            self::ZIPCODE_MAX_LENGTH
        )->validate($deliveryZipCode)) {
            Core::setLastError(DELIVERYZIPCODE_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    public function deliveryAddressType($deliveryAddressType) : bool
    {
        if (!V::stringType()->validate($deliveryAddressType)) {
            Core::setLastError(DELIVERYADDRESSTYPE_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    //验证送货需要室内搬运范围：[0,1]
    public function pickupNeedTransport($pickupNeedTransport) : bool
    {
        if (!in_array($pickupNeedTransport, OrderLTL::NEEDTRANSPORT)) {
            Core::setLastError(PICKUPNEEDTRANSPORT_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    //验证送货需要卡车升降台范围：[0,1]
    public function pickupNeedLiftgate($pickupNeedLiftgate) : bool
    {
        if (!in_array($pickupNeedLiftgate, OrderLTL::NEEDLIFTGATE)) {
            Core::setLastError(PICKUPNEEDLIFTGATE_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    //验证送货需要室内搬运范围：[0,1]
    public function deliveryNeedTransport($deliveryNeedTransport) : bool
    {
        if (!in_array($deliveryNeedTransport, OrderLTL::NEEDTRANSPORT)) {
            Core::setLastError(DELIVERYNEEDTRANSPORT_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    //验证送货需要卡车升降台范围：[0,1]
    public function deliveryNeedLiftgate($deliveryNeedLiftgate) : bool
    {
        if (!in_array($deliveryNeedLiftgate, OrderLTL::NEEDLIFTGATE)) {
            Core::setLastError(DELIVERYNEEDLIFTGATE_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    const PONUMBER_MIN_LENGTH = 1;
    const PONUMBER_MAX_LENGTH = 200;
    public function poNumber($poNumber) : bool
    {
        if (!V::stringType()->length(
            self::PONUMBER_MIN_LENGTH,
            self::PONUMBER_MAX_LENGTH
        )->validate($poNumber)) {
            Core::setLastError(PONUMBER_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    //验证取货车辆类型范围：[1,2]
    public function pickupVehicleType($pickupVehicleType) : bool
    {
        if (!in_array($pickupVehicleType, OrderLTL::PICKUPVEHICLETYPE)) {
            Core::setLastError(PICKUPVEHICLETYPE_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    const DESCRIPTION_MIN_LENGTH = 1;
    const DESCRIPTION_MAX_LENGTH = 50;
    //验证货物描述长度：1-50个字符
    public function description($description) : bool
    {
        if (!V::stringType()->length(
            self::DESCRIPTION_MIN_LENGTH,
            self::DESCRIPTION_MAX_LENGTH
        )->validate($description)) {
            Core::setLastError(DESCRIPTION_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    public function deliveryDescription($deliveryDescription) : bool
    {
        if (!V::stringType()->length(
            self::DESCRIPTION_MIN_LENGTH,
            self::DESCRIPTION_MAX_LENGTH
        )->validate($deliveryDescription)) {
            Core::setLastError(DELIVERYDESCRIPTION_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    public function pickupRequirement($pickupRequirement) : bool
    {
        return $this->requirement($pickupRequirement, PICKUPREQUIREMENT_FORMAT_INCORRECT);
    }

    public function deliveryRequirement($deliveryRequirement) : bool
    {
        return $this->requirement($deliveryRequirement, DELIVERYREQUIREMENT_FORMAT_INCORRECT);
    }

    const REQUIREMENT_KEYS = array(
        "category",
        "day",
        "startTime",
        "endTime"
    );
    // 验证取货/送货要求格式为数组，且对应字段都存在
    // 取货错误码：PICKUPREQUIREMENT_FORMAT_INCORRECT
    // 送货错误码：DELIVERYREQUIREMENT_FORMAT_INCORRECT
    public function requirement($requirement, $code) : bool
    {
        if (empty($requirement) || !V::arrayType()->validate($requirement)) {
            Core::setLastError($code);
            return false;
        }

        foreach ($requirement as $key => $value) {
            if (!in_array($key, self::REQUIREMENT_KEYS)) {
                Core::setLastError($code);
                return false;
            }
            if ($key == 'category') {
                $category = $value;
                if (!$this->category($value)) {
                    return false;
                }
            }
            if ($category == OrderLTL::CATEGORY['ADDRESS_OPEN']) {
                if ($key == 'day' && !$this->bookingPickupDate($value)) {
                    return false;
                }
                if ($key == 'startTime' && !$this->startTime($value)) {
                    return false;
                }
                if ($key == 'endTime' && !$this->endTime($value)) {
                    return false;
                }
            }
        }
        return true;
    }

    //验证取货/送货要求类型范围：[0,1,2,3,4]
    public function category($category) : bool
    {
        if (!in_array($category, OrderLTL::CATEGORY)) {
            Core::setLastError(REQUIREMENT_CATEGORY_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    //验证category=2时，开始时间
    public function startTime($startTime) : bool
    {
        if (!V::stringType()->validate($startTime)) {
            Core::setLastError(REQUIREMENT_STARTTIME_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    //验证category=2时，结束时间
    public function endTime($endTime) : bool
    {
        if (!V::stringType()->validate($endTime)) {
            Core::setLastError(REQUIREMENT_ENDTIME_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    public function readyTime($readyTime) : bool
    {
        if (!V::stringType()->validate($readyTime)) {
            Core::setLastError(READYTIME_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    public function closeTime($closeTime) : bool
    {
        if (!V::stringType()->validate($closeTime)) {
            Core::setLastError(CLOSETIME_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    public function deliveryReadyTime($deliveryReadyTime) : bool
    {
        if (!V::stringType()->validate($deliveryReadyTime)) {
            Core::setLastError(DELIVERYREADYTIME_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    public function deliveryCloseTime($deliveryCloseTime) : bool
    {
        if (!V::stringType()->validate($deliveryCloseTime)) {
            Core::setLastError(DELIVERYCLOSETIME_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    //验证取货地址：整数
    public function address($address) : bool
    {
        if (!V::numeric()->validate($address)) {
            Core::setLastError(ORDERLTL_ADDRESS_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    //验证送货地址：整数
    public function deliveryAddress($deliveryAddress) : bool
    {
        if (!V::numeric()->validate($deliveryAddress)) {
            Core::setLastError(ORDERLTL_DELIVERYADDRESS_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    //验证散板订单：数组
    public function orderLTL($orderLTL) : bool
    {
        if (!V::arrayType()->validate($orderLTL)) {
            Core::setLastError(ORDERLTL_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }

    const PRICEAPIIDENTIFY_MIN_LENGTH = 1;
    const PRICEAPIIDENTIFY_MAX_LENGTH = 500;
    public function priceApiIdentify($priceApiIdentify) : bool
    {
        if (!V::stringType()->length(
            self::PRICEAPIIDENTIFY_MIN_LENGTH,
            self::PRICEAPIIDENTIFY_MAX_LENGTH
        )->validate($priceApiIdentify)) {
            Core::setLastError(PRICEAPIIDENTIFY_FORMAT_INCORRECT);
            return false;
        }
        return true;
    }
}
